import com.sun.xml.internal.bind.v2.model.core.ID;

/**
 * @ClassName KP7_mathrandom
 * @Description: TODO
 * @Author: JCC
 * @CreateTime: 2023/10/8 11:26
 */
public class KP7_mathrandom {


    public static void main(String[] args) {
        System.out.println("测试random等概率取到[0,1)随机数");
        // Math.random() -> double -> [0,1)
        double randNum = Math.random();
        int testTimes = 10000000;
        int count = 0;
        for (int i = 0; i < testTimes; i++) {
            if (Math.random() < 0.7) {
                count++;
            }
        }
        System.out.println((double) count / testTimes);
        System.out.println("============================");

        System.out.println("测试random等概率取到[0,?)随机数");
        count = 0;
        for (int i = 0; i < testTimes; i++) {
            if (Math.random() * 8 < 6) {
                count++;
            }
        }
        System.out.println((double) count / testTimes);
        System.out.println((double) 6 / (double) 8);

        System.out.println("============================");
        System.out.println("测试random等概率取到[0,K)随机数");

        // Math.random() * K -> double -> [0,K)
        // (int) (Math.random() * K) -> [0,K-1]
        int K = 9;
        int[] counts = new int[K];
        for (int i = 0; i < testTimes; i++) {
            int rand = (int) (Math.random() * K);
            counts[rand]++;
        }
        for (int i = 0; i < counts.length; i++) {
            System.out.println(i + "这个数出现的次数是：" + counts[i]);
        }

        System.out.println("============================");
        System.out.println("============================");
        // 由以上结论推出，Math.random的到的随机数[0,1)是等概率出现的
        // 所以 P[0,1) -> P[0,x) (x <= 1) --> x
        // 由此提出如何使其成为 x^2 ?
        count = 0;
        double x = 0.6;
        for (int i = 0; i < testTimes; i++) {
            if (xPower2() < x) {
                count++;
            }
        }
        System.out.println(Math.pow(x, 2));
        System.out.println((double) count / testTimes);
        System.out.println("----------------------------");

        // 再提出如何使其成为 x^3 ?
        count = 0;
        x = 0.6;
        for (int i = 0; i < testTimes; i++) {
            if (xPower3() < x) {
                count++;
            }
        }
        System.out.println(Math.pow(x, 3));
        System.out.println((double) count / testTimes);

        System.out.println("----------------------------");
        // 既然我们知道了求Math.random取到的随机数[0,x)(x <= 1)的概率是x
        // x^2 则是通过Math.max(Math.random(), Math.random())
        // 因为Math.max想要取到[0,x)的概率就要使两次取到[0,x)的概率都是x 即 x && x  --> x^2

        // 那么用Math.min是什么值呢？
        // Math.min(Math.random(), Math.random())
        // Math.min想要取到[0,x)的概率我们暂时还不能确定
        // 因为它有很3种情况
        // 1、[0,x) && [1-x,1)
        // 2、[1-x,1) && [0,x)
        // 3、[0,x) && [0,x)
        // 但是我们唯一能确定的就是取不到[0,x)的概率 --> 1-x
        // Math.min(Math.random(), Math.random())
        // Math.min想要取不到[0,x)的概率是1-x,那么 1-x && 1-x --> (1-x)^2
        // 所以取到[0,x]的概率就是 1-(1-x)^2
        // 我们用实验数据来证明

        x = 0.8;
        count = 0;
        for (int i = 0; i < testTimes; i++) {
            if (xMinPower2() < x) {
                count++;
            }
        }
        System.out.println(1 - Math.pow((double) 1 - x, 2));
        System.out.println((double) count / testTimes);
    }

    public static double xPower2() {
        return Math.max(Math.random(), Math.random());
    }

    public static double xPower3() {
        return Math.max(Math.random(), Math.max(Math.random(), Math.random()));
    }

    public static double xMinPower2() {
        return Math.min(Math.random(), Math.random());
    }
}
